#include <stdlib.h>
#include <stdio.h>
#include "lut.h"
#include "calque.h"

Lut* initLut(){
	int i;
	Lut* lut = NULL;
	lut = (Lut*)malloc(sizeof(Lut));
	lut->tabR = malloc(sizeof(int)*256);
	if(lut->tabR == NULL){
		printf("Erreur d'allocation\n");
		exit(1);
	}
	lut->tabG = malloc(sizeof(int)*256);
	if(lut->tabG == NULL){
		printf("Erreur d'allocation\n");
		exit(1);
	}
	lut->tabB = malloc(sizeof(int)*256);
	if(lut->tabB == NULL){
		printf("Erreur d'allocation\n");
		exit(1);
	}
	lut->nextLut = NULL;

	for (i = 0; i < 256; i++){
		lut->tabR[i] = i;
		lut->tabG[i] = i;
		lut->tabB[i] = i;
	}
	return lut;
}

ListeLut lastLut(ListeLut l){//Attention ne va pas à NULL
	Lut* c = l;
	while(c->nextLut != NULL){
		c = c->nextLut;
	}
	return c;
}

ListeLut addlum(ListeLut l, unsigned char val){
	Lut* lut = initLut();
	int i;

	printf("%d\n",val );
	printf("test addlum\n");

	for (i = 0; i < 256; i++){
		// array Red
		if ((lut->tabR[i] + val) >= 255){
			lut->tabR[i] = 255;
		}
		else{
			lut->tabR[i] = lut->tabR[i] + val;
		}

		// array green
		if ((lut->tabG[i] + val) >= 255){
			lut->tabG[i] = 255;
		}
		else{
			lut->tabG[i] = lut->tabG[i] + val;
		}

		// array Blue
		if ((lut->tabB[i] + val) >= 255){
			lut->tabB[i] = 255;
		}
		else{
			lut->tabB[i] = lut->tabB[i] + val;
		}
	}
	return addLut(l, lut);
}

ListeLut dimlum(ListeLut l, unsigned char val){
	Lut* lut = initLut();
	int i;

	for (i = 0; i <= 255; i++){
		// array Red
		if ((lut->tabR[i] - val) <= 0){
			lut->tabR[i] = 0;
		}
		else{
			lut->tabR[i] = lut->tabR[i] - val;
		}

		// array green
		if ((lut->tabG[i] - val) <= 0){
			lut->tabG[i] = 0;
		}
		else{
			lut->tabG[i] = lut->tabG[i] - val;
		}

		// array Blue
		if ((lut->tabB[i] - val) <= 0){
			lut->tabB[i] = 0;
		}
		else{
			lut->tabB[i] = lut->tabB[i] - val;
		}
	}
	return addLut(l, lut);
}

ListeLut addcon(ListeLut l, unsigned char val){
	Lut* lut = initLut();
	int i;

	for (i = 0; i <128; i++){
		// array Red
		if ((lut->tabR[i] - val) <= 0){
			lut->tabR[i] = 0;
		}
		else{
			lut->tabR[i] = lut->tabR[i] - val;
		}

		// array green
		if ((lut->tabG[i] - val) <= 0){
			lut->tabG[i] = 0;
		}
		else{
			lut->tabG[i] = lut->tabG[i] - val;
		}

		// array Blue
		if ((lut->tabB[i] - val) <= 0){
			lut->tabB[i] = 0;
		}
		else{
			lut->tabB[i] = lut->tabB[i] - val;
		}
	}
	for (i = 128; i <=255; i++){
		// array Red
		if ((lut->tabR[i] + val) >= 255){
			lut->tabR[i] = 255;
		}
		else{
			lut->tabR[i] = lut->tabR[i] + val;
		}

		// array green
		if ((lut->tabG[i] + val) >= 255){
			lut->tabG[i] = 255;
		}
		else{
			lut->tabG[i] = lut->tabG[i] + val;
		}

		// array Blue
		if ((lut->tabB[i] + val) >= 255){
			lut->tabB[i] = 255;
		}
		else{
			lut->tabB[i] = lut->tabB[i] + val;
		}
	}
	return addLut(l, lut);
}

ListeLut dimcon(ListeLut l, unsigned char val){
	Lut* lut = initLut();
	int i;

	for (i = 0; i <128; i++){
		// array Red
		if ((lut->tabR[i] + val) >= 128){
			lut->tabR[i] = 128;
		}
		else{
			lut->tabR[i] = lut->tabR[i] + val;
		}

		// array green
		if ((lut->tabG[i] + val) >= 128){
			lut->tabG[i] = 128;
		}
		else{
			lut->tabG[i] = lut->tabG[i] + val;
		}

		// array Blue
		if ((lut->tabB[i] + val) >= 128){
			lut->tabB[i] = 128;
		}
		else{
			lut->tabB[i] = lut->tabB[i] + val;
		}
	}
	for (i = 128; i <=255; i++){
		// array Red
		if ((lut->tabR[i] - val) <= 128){
			lut->tabR[i] = 128;
		}
		else{
			lut->tabR[i] = lut->tabR[i] - val;
		}

		// array green
		if ((lut->tabG[i] - val) <= 128){
			lut->tabG[i] = 128;
		}
		else{
			lut->tabG[i] = lut->tabG[i] - val;
		}

		// array Blue
		if ((lut->tabB[i] - val) <= 128){
			lut->tabB[i] = 128;
		}
		else{
			lut->tabB[i] = lut->tabB[i] - val;
		}
	}
	return addLut(l, lut);
}

ListeLut invert(ListeLut l){
	Lut* lut = initLut();
	int i;

	for (i = 0; i <= 255; i++){
		// array Red
			lut->tabR[i] = 255 - i;
		// array Green
			lut->tabG[i] = 255 - i;
		// array Blue
			lut->tabB[i] = 255 - i;
	}
	return addLut(l, lut);
}

ListeLut sepia(ListeLut l) {
	Lut* lut = initLut();
	int i = 0;

	for(i=0; i<256; i++) {
		// Rouge
		lut->tabR[i] = i + 80;
		if(lut->tabR[i] > 255){
			lut->tabR[i] = 255;
		}
		lut->tabR[i] = lut->tabR[i];

		// Vert
		lut->tabG[i] = i + 30;
		if(lut->tabG[i] > 255){
			lut->tabG[i] = 255;
		}
		lut->tabG[i] = lut->tabG[i];

		// Bleu
		lut->tabB[i] = i - 40;
		if(lut->tabB[i] < 0){
			lut->tabB[i] = 0;
		}
		lut->tabB[i] = lut->tabB[i];
	}
	return addLut(l, lut);
}

ListeLut addLut(ListeLut l, Lut* lut){
	if (l == NULL){
		l = lut;
		l->nextLut = NULL;// Remplir nextLut a NULL
	}
	else{//Sinon remplir le next lut du lut précédent qui vallait null par le nouveau lut
		ListeLut t = l;
		while(t->nextLut != NULL){
			t = t->nextLut;
		}
		t->nextLut = lut;
		t = t->nextLut;
		t->nextLut = NULL;
		t = l;

		while(t != NULL){
			printf("lut : %d - liste lut : %d \n", lut, t);
			t = t->nextLut;
		}
	}
	return l;
}